//***********************************************************************
//	File:		Player.cpp
//	Author:		
//	Course:		SGP 1405
//	Purpose:	
//***********************************************************************
//***********************************************************************
//	Purposfully left blank for all comments regarding this file 
//	
//	
//	
//***********************************************************************



#include "Player.h"
#include "Bullet.h"

#include "../SGD Wrappers/SGD_Event.h"
#include "../SGD Wrappers/SGD_MessageManager.h"
#include "../Message/CreateProjectileMessage.h"
#include "../Message/UseAbilityMessage.h"

#include "../source/Game.h"
#include "../GameStates/Play.h"
#include "../TileSystem/TileSystem.h"

#include "../SGD Wrappers/SGD_InputManager.h"
#include "../SGD Wrappers/SGD_GraphicsManager.h"
#include "../SGD Wrappers/SGD_AudioManager.h"

Player::Player(float posX, float posY, bool sniper)
: SGD::Listener(this)
{
	SetAcceleration ( { 0 , 0 } );
	SetAltWepType(-1);
	SetAttackRateAir(1); 
	SetAttackRateGround(.1f); 
	SetAttackTimer(0); 
	SetBreathCost(20); 
	SetConcussionCDL(5);
	SetConcussionTimer(0);
	SetConfuseCDL(8);
	SetConfuseTimer(0); 
	SetCrossHairImg(Game::GetInstance()->GetAirPlayerImg());
	SetCryoNetCDL(6);
	SetCryoNetTimer(0); 
	SetCurrAmmo(30);
	SetCurrWeapon(ENT_FLAME);
	SetDashingCDL(4); 
	SetDashingCost(25);
	SetDashingTimer(0); 
	SetDynamicFrictionCoefficient(.6f); 
	SetGrenadeCDL(6); 
	SetGrenadeTimer(0);
	SetHealth(100);
	SetHealthRegenRate(5); 
	SetHoldBreath(false); 
	SetImage(Game::GetInstance()->GetGroundPlayerImg());
	SetInitials("USA");
	SetIsDashing(false); 
	SetIsProne(false); 
	SetIsSniper(sniper); 
	SetKnockbackCDL(5); 
	SetKnockbackTimer(0); 
	SetLives(3); 
	SetMass(90); 
	SetMaxAmmo(30); 
	SetMaxHealth(100); 
	SetMaxSpeed(150);
	SetMaxStamina(100); 
	SetPassable(false);
	SetPosition(SGD::Point{ posX, posY }); 
	SetReloadCDL(.75f); 
	SetReloadTimer(0); 
	SetReticleBreathVelocity(75); 
	SetReticleVelocity(150);
	SetRotation(0); 
	SetScore(0);
	SetSize(SGD::Size{ 64, 64 }); 
	SetSpeed(150); 
	SetSprintCost(10);
	SetSprintSpeed(200);
	SetStamina(100); 
	SetStaminaRegenRate(15);
	SetStaticFrictionCoefficient(.8f);
	//SetTakeDamage(); // particle emitter
	//SetTakeDamageSfx(); 
	SetVelocity(SGD::Vector{ 0, -1 }); 
	RegisterForEvent("INCREASE_SCORE");
	
}

Player::~Player()
{
	UnregisterFromEvent("INCREASE_SCORE");
}

void Player::Update(float dt)
{
	if (m_bIsSniper == true)
	{
		AirUpdate(dt);
	}
	else
	{
		GroundUpdate(dt); 
	}
	//Entity::Update(dt); 
}

void Player::Render()
{
	if (m_bIsSniper == true)
	{
		AirRender();
	}
	else
	{
		GroundRender();
	}
}

void Player::HandleCollision(const IEntity* pOther)
{
	switch (pOther->GetType())
	{
	case ENT_BULLET:
		const Bullet* pBullet = dynamic_cast<const Bullet*>(pOther);
		ModifyHealth(-pBullet->GetDamage()); 
		if (SGD::AudioManager::GetInstance()->IsAudioPlaying(GetTakeDamageSfx()) == false)
			SGD::AudioManager::GetInstance()->PlayAudio(GetTakeDamageSfx()); 
	}
}

void Player::HandleEvent( const SGD::Event* pEvent)
{
	
}

SGD::Rectangle Player::GetRect() const
{
	SGD::Rectangle rect;
	
	rect.left = m_ptPosition.x - (m_szSize.width  * 0.5f);
	rect.top = m_ptPosition.y - (m_szSize.height  * 0.5f);
	rect.right = rect.left + m_szSize.width;
	rect.bottom = rect.top + m_szSize.height;

	return rect;
}

void Player::ModifyHealth(float hpAmount)
{
	SetHealth(GetHealth() + hpAmount); 

	if (GetHealth() <= 0)
	{
		SetHealth(0); 
		m_nLives--; 
		if (m_nLives == 0)
		{
			BitmapFont* pFont = Game::GetInstance()->GetFont(); 
			pFont->Draw("Game Over", (int)Game::GetInstance()->GetScreenWidth() / 2 - 40,
				 (int)Game::GetInstance()->GetScreenHeight() / 2, 1, { 255, 200, 0 }); 
		}
	}
}

void Player::ApplyFriction(float dt)
{

}


//Player specific
void Player::ModifyScore(int value)
{
	SetScore(GetScore() + value); 
}

//Private Functions
void Player::AirUpdate(float dt)
{
	SGD::InputManager* pInput = SGD::InputManager::GetInstance(); 
	SGD::Vector movement = pInput->GetLeftJoystick(1); 

	if (pInput->IsButtonDown(1, 0) == true)
	{
		SetHoldBreath(true); 
	}
	if (pInput->IsButtonReleased(1, 0))
	{
		SetHoldBreath(false); 
	}

	if (pInput->IsButtonPressed(1, 1))
	{
		UseAbilityMessage* useAbility = new UseAbilityMessage(this, ENT_CRYONET);
		useAbility->QueueMessage(); 
	}

	if (pInput->IsButtonPressed(1, 4) || pInput->IsKeyPressed(SGD::Key::J) )
	{
		UseAbilityMessage* useAbility = new UseAbilityMessage(this, ENT_CONCUSSIONBLAST);
		useAbility->QueueMessage(); 
	}

	if (pInput->IsButtonPressed(1, 5))
	{
		UseAbilityMessage* useAbility = new UseAbilityMessage(this, ENT_CONFUSION_GAS);
		useAbility->QueueMessage();
	}

	if (pInput->GetTrigger(1))
	{
		CreateProjectileMessage* projectileToCreate = new CreateProjectileMessage(this, ENT_SNIPER_BULLET);
		projectileToCreate->QueueMessage();
	}


	if (movement.x < -.1 || pInput->IsKeyDown(SGD::Key::K))
	{
		m_ptPosition.x -= 300 * dt; 
	}
	else if (movement.x > .1 || pInput->IsKeyDown(SGD::Key::L))
	{
		m_ptPosition.x += 300 * dt; 
	}

	if (movement.y < -.1 || pInput->IsKeyDown(SGD::Key::O))
	{
		m_ptPosition.y -= 300 * dt; 
	}
	else if (movement.y > .1 || pInput->IsKeyDown(SGD::Key::Comma))
	{
		m_ptPosition.y += 300 * dt; 
	}


}

void Player::GroundUpdate(float dt)
{
	int width = (int)Game::GetInstance()->GetScreenWidth(); 
	int height = (int)Game::GetInstance()->GetScreenHeight(); 

	SGD::Point cameraPos = Play::GetInstance()->GetCameraPos(); 

	SGD::InputManager* pInput = SGD::InputManager::GetInstance();
	SGD::Vector movement = pInput->GetLeftJoystick(0);
	m_vGetRightStick = pInput->GetRightJoystick(0);
 

	if (pInput->IsButtonPressed(0, 0) == true)
	{
		SetIsDashing(true);
	}
	if (pInput->IsButtonDown(0, 8) == true)
	{
		SetIsProne(true);
	}
	else
	{
		SetIsProne(false);
	}
	if (pInput->IsKeyPressed(SGD::Key::K))
	{
		ModifyHealth(-GetHealth()); 
	}

	if (m_bIsProne == true)
	{
		SetSpeed(0); 
	}
	else
	{
		SetSpeed(150); 
	}

	SGD::Rectangle projected = GetRect();
	SGD::Point move;
	if (movement.x < -.1 || pInput->IsKeyDown(SGD::Key::A))
	{
		move.x -= GetSpeed()*dt; 
	}
	else if (movement.x > .1 || pInput->IsKeyDown(SGD::Key::D))
	{
		move.x += GetSpeed()*dt;
	}

	if (movement.y > .1 || pInput->IsKeyDown(SGD::Key::S))
	{
		move.y += GetSpeed()*dt;
	}
	else if (movement.y < -.1 || pInput->IsKeyDown(SGD::Key::W))
	{
		move.y -= GetSpeed()*dt;
	}


	
	SGD::Vector findRotation = { 0, -1 };
	float angle = m_vGetRightStick.ComputeAngle(findRotation);

	if (m_vGetRightStick.ComputeLength() > 0.9f)
	{

		if (findRotation.ComputeSteering(m_vGetRightStick) > 0)
		{
			SetRotation(angle);
		}
		else
		{
			SetRotation(-angle);
		}
	}
	


	



	if (pInput->GetTrigger(0) || pInput->IsKeyDown(SGD::Key::F))
	{
		CreateProjectileMessage* projectileToCreate = new CreateProjectileMessage(this, GetCurrWeapon()); 
		projectileToCreate->QueueMessage();
	}
	projected.left += move.x;
	projected.right += move.x;
	if (TILESYSTEM->CheckWorld( projected ) == SGD::Rectangle ( 0.0f , 0.0f , 0.0f , 0.0f ) )
	{
		m_ptPosition.x = projected.left + m_szSize.width/2.0f;
	}
	projected = GetRect();
	projected.top += move.y;
	projected.bottom += move.y;
	if (TILESYSTEM->CheckWorld( projected ) == SGD::Rectangle ( 0.0f , 0.0f , 0.0f , 0.0f ) )
	{
		m_ptPosition.y = projected.top + m_szSize.height/2.0f;
	}

}

void Player::AirRender(void)
{
	SGD::GraphicsManager* draw =
		SGD::GraphicsManager::GetInstance(); 

	SGD::Point cameraPos = Play::GetInstance()->GetCameraPos(); 

	SGD::Point offset = GetPosition() - GetSize() / 2; 
	offset.x -= cameraPos.x; 
	offset.y -= cameraPos.y; 

	draw->DrawTextureSection(GetCrosshairImg(), offset, SGD::Rectangle{ 6, 6, 68, 68 },
		0, { GetSize().width / 2, GetSize().height / 2 });
}

void Player::GroundRender(void)
{
	SGD::GraphicsManager* draw = 
		SGD::GraphicsManager::GetInstance();

	SGD::Point cameraPos = Play::GetInstance()->GetCameraPos(); 

	SGD::Point offset = GetPosition() - GetSize() / 2.0f;
	offset.x -= cameraPos.x; 
	offset.y -= cameraPos.y;

	SGD::Rectangle render = GetRect();
	render.left -= cameraPos.x;
	render.right -= cameraPos.x;
	render.top -= cameraPos.y;
	render.bottom -= cameraPos.y;

	

	draw->DrawTextureSection(GetImage(), offset, SGD::Rectangle{ 0, 0, 64, 64 },
		GetRotation () , { GetSize ().width / 2 , GetSize().height / 2} , {255, 255, 255} , { 1.0f , 1.0f });
	draw->DrawRectangle(render, {0, 0,0,0}, {255, 0,0,0}, 2);

}




